/********************************************************************************
 * Project Name		[JavaSE_Fundamentals]
 * File Name     	[GenericsBoundary.java]
 * Creation Date 	[2015-01-01]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ********************************************************************************/
package generics;

import static java.util.Calendar.DECEMBER;

import java.io.Serializable;
import java.util.GregorianCalendar;

/**
 * 泛型参数的边界
 * 
 * 上界: 使用extends声明, 表示参数化的类型可能是所指定的类型或者是此类型的子类<br/>
 * 下界: 使用super进行声明, 表示参数化的类型可能是所指定的类型, 或者是此类型的父类型, 直至Object<br/>
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 * 
 */
public class GenericsBoundary {

	/**
	 * 
	 * 当存在多个接口时, 应当将标记接口放在最后
	 * 
	 * @param arrays
	 * @return 最大值和最小值组成的Pair对象
	 */
	public static <T extends Comparable<? super T> & Serializable> Pair<T> minmax(T[] arrays) {
		if (arrays == null || arrays.length == 0) {
			return null;
		}

		T min = arrays[0];
		T max = arrays[0];
		for (int i = 0; i < arrays.length; i++) {
			if (min.compareTo(arrays[i]) > 0) {
				min = arrays[i];
			}
			if (max.compareTo(arrays[i]) < 0) {
				max = arrays[i];
			}
		}
		return new Pair<T>(min, max);
	}

	public static void main(String[] args) {
		String[] arrays = { "D", "A", "C", "B", "E" };
		Pair<String> p = minmax(arrays);
		System.out.println(p);

		GregorianCalendar[] birthdays = { new GregorianCalendar(1990, DECEMBER, 7),
				new GregorianCalendar(1800, DECEMBER, 10), new GregorianCalendar(2000, DECEMBER, 20), };
		// 当调用一个泛型方法时, 在方法名前的尖括号中放入具体的类型, 也可以省略参数类型
		Pair<GregorianCalendar> p2 = GenericsBoundary.<GregorianCalendar> minmax(birthdays);
		System.out.println("Min : " + p2.getFirst().getTime());
		System.out.println("Max : " + p2.getSecond().getTime());
	}
}
